package com.kuang.myInterger;

/*
*   给你一个 32 位的有符号整数 x ，返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−2^31,  2^31 − 1] ，就返回 0。
假设环境不允许存储 64 位整数（有符号或无符号）。

示例 1：
输入：x = 123
输出：321

示例 2：
输入：x = -123
输出：-321

示例 3：
输入：x = 120
输出：21

示例 4：
输入：x = 0
输出：0
* */


/**
 * @author kjx
 */
public class ReverseInteger {

    //第一种思路直接转字符串反转即可,但是要判断一下正负
    public static int reverse(int x) {
        boolean isNegative = false;   //如果是负数则为true
        if (x < 0) {
            //为了避免临界情况，如最小的三十二位，因此这里转负也需要用long
            long longX = x;
            longX = -longX;
            isNegative = true;
            if (longX > Integer.MAX_VALUE) {
                return 0;
            } else {
                x = (int) longX;
            }
        }
        //设置两个变量为了判断反转后是否超出32位
        long testNumLong;
        int testNumInt;
        //转换为字符串
        String valueStr = String.valueOf(x);
        //字符串反转
        String resStr = reverseStr(valueStr);

        //判断是否超出32位
        testNumLong = Long.parseLong(resStr); // 由于不知道反转后是否超出,因此先用long类型存储

        if (testNumLong > Integer.MAX_VALUE) {
            return 0;
        } else {
            testNumInt = (int) testNumLong; // 将 long 值转换为 int 类型
        }

        //判断正负
        testNumInt = isNegative ? -testNumInt : testNumInt;

        return testNumInt;
    }


    //字符串反转
    public static String reverseStr(String str) {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = str.length() - 1; i >= 0; i--) {
            stringBuilder.append(str.charAt(i));
        }
        return stringBuilder.toString();
    }


    //这里提供题解里面的一种同样用字符串反转的最简洁的代码
    public int reverse2(int x) {
        StringBuilder sb = new StringBuilder();
        sb.append(Math.abs(x));

        try {
            int result = Integer.parseInt(sb.reverse().toString());
            return x > 0 ? result : -result;
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }

        return 0;
    }


    //方案三，唯一真神还是当初学的最简单的方法：
    //这种方法只涉及到了最简单的运算，没有涉及到字符串等操作，用字符串涉及到了对象，对对象的访问啥的速度一定更慢
    //还不如返璞归真，这种0ms速度最快，尽管宏观上的时间复杂度都是O(n)，但是O(n)之中亦有高低！
    public int reverse3(int x) {
        int res = 0;
        while (x != 0) {
            //每次取末尾数字
            int tmp = x % 10;
            //判断是否 大于 最大32位整数
            if (res > 214748364 || (res == 214748364 && tmp > 7)) {
                return 0;
            }
            //判断是否 小于 最小32位整数
            if (res < -214748364 || (res == -214748364 && tmp < -8)) {
                return 0;
            }
            res = res * 10 + tmp;
            x /= 10;
        }
        return res;
    }


    //方案一，自带的StringBuilder
    //方案二，charAt
    //方案三，toCharArray方法
    //方案四，利用栈，压栈出栈来逆序
    //方案五，二分法逆序字符串数组
    //这里突发奇想，对字符串的反转的多种方法对比了一下，这里有篇文章：https://blog.csdn.net/servermanage/article/details/102662085

    public static void main(String[] args) {
        System.out.println(reverse(-12345));
        System.out.println(reverse(12345));
        System.out.println(reverse(1200000));
        System.out.println(reverse(-1200000));
        System.out.println(reverse(Integer.MAX_VALUE + 123213123));
        System.out.println(reverse(-2147483648));
    }
}
